let kk = /\{\{(.+?)\}\}/g;

// 真 => 虚拟vnode
function getVnode(node) {
  let nodeType = node.nodeType;
  let _vnode = null;
  if (nodeType === 1) {
    let targName = node.nodeName;
    let attrs = node.attributes; // attributes 返回是个伪数组
    let _attrObject = {};
    for (let i = 0; i < attrs.length; i++) {
      // attrs[i] 是属性节点
      _attrObject[attrs[i].nodeName] = attrs[i].nodeValue;
    }
    _vnode = new Vnode(targName, _attrObject, undefined, nodeType);
    let childNodes = node.childNodes;
    for (let i = 0; i < childNodes.length; i++) {
      _vnode.appendChild(getVnode(childNodes[i]));
    }
  } else if (nodeType === 3) {
    _vnode = new Vnode(undefined, undefined, node.nodeValue, nodeType);
  }
  return _vnode;
}
// vnode => 真
function paseVnode(vnode) {
  let type = vnode.type;
  let _node = null;
  if (type === 3) {
    return document.createTextNode(vnode.value);
  } else if (type === 1) {
    _node = document.createElement(vnode.tag);
    //属性
    let data = vnode.data;
    Object.keys(data).forEach((item) => {
      let attrName = item;
      let attrValue = data[item];
      _node.setAttribute(attrName, attrValue);
    });
    //子元素
    let children = vnode.children;
    children.forEach((subvnode) => {
      _node.appendChild(paseVnode(subvnode));
    });

    return _node;
  }
}

function getValueByPath(data, path) {
  let pathArr = path.split(".");
  let res = data;
  let prop;
  while ((prop = pathArr.shift())) {
    res = res[prop];
  }
  return res;
}
//  将带有坑的vnode 与data 生成新的vnode
function combine(vnode, data) {
  let _tag = vnode.tag;
  let _type = vnode.type;
  let _data = vnode.data;
  let _value = vnode.value;
  let _children = vnode.children;
  let _vnode = null;

  if (_type === 3) {
    // 对文本处理
    _value = _value.replace(kk, function (_, g) {
      return getValueByPath(data, g.trim());
    });
    _vnode = new Vnode(_tag, _data, _value, _type);
  } else if (_type === 1) {
    _vnode = new Vnode(_tag, _data, _value, _type);
    _children.forEach((_subVnode) =>
      _vnode.appendChild(combine(_subVnode, data))
    );
  }
  return _vnode;
}
